package com.zmwx.auth.domain.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.google.common.base.Preconditions;
import com.google.gson.Gson;
import com.zmwx.auth.common.enums.IsDeletedFlagEnum;
import com.zmwx.auth.domain.constants.AuthConstant;
import com.zmwx.auth.domain.convert.AuthUserBOToConverter;
import com.zmwx.auth.domain.entityDO.AuthUserBO;
import com.zmwx.auth.domain.redis.RedisUtil;
import com.zmwx.auth.domain.service.AuthUserDomainService;
import com.zmwx.auth.infra.basic.entity.*;
import com.zmwx.auth.infra.basic.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 领域层
 */
@Slf4j
@Service
public class AuthUserDomainServiceImpl implements AuthUserDomainService {
    @Resource
    private AuthUserService authUserService;
    @Resource
    private AuthUserRoleService authUserRoleService;
    @Resource
    private AuthRoleService authRoleService;
    @Resource
    private TransactionTemplate transactionTemplate;
    @Resource
    private AuthPermissionService authPermissionService;
    @Resource
    private AuthRolePermissionService authRolePermissionService;

    @Resource
    private RedisUtil redisUtil;

    private String authPermissionPrefix = "auth.permission";

    private String authRolePrefix = "auth.role";

    private String salt = "zmwx";//加盐字符串

    private static final String LOGIN_PREFIX = "loginCode";

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean register(AuthUserBO authUserBO) {
        //判断用户是否已经存在
        AuthUser existAuthUser = new AuthUser();
        existAuthUser.setUserName(authUserBO.getUserName());
        List<AuthUser> existUser = authUserService.queryByCondition(existAuthUser);
        if (existUser.size() > 0) {
            return true;
        }
        AuthUser authUser = AuthUserBOToConverter.INSTANCE.convertToEntity(authUserBO);
        //考虑是微信登陆的 没有密码
        if (StringUtils.isNotBlank(authUser.getPassword())) {
            authUser.setPassword(SaSecureUtil.md5BySalt(authUser.getPassword(), salt));
        }
        if (StringUtils.isBlank(authUser.getAvatar())) {
            authUser.setAvatar("http://117.72.10.84:9000/user/icon/微信图片_20231203153718(1).png");
        }
        Integer count = authUserService.insert(authUser);
        //建立角色关联
        AuthRole authRole = new AuthRole();
        authRole.setRoleKey(AuthConstant.NORMAL_USER);
        AuthRole authRoleResult = authRoleService.queryBYCondition(authRole);
        Long roleId = authRoleResult.getId();
        Long userId = authUser.getId();//插入时候自动赋值返回的id
        AuthUserRole authUserRole = new AuthUserRole();
        authUserRole.setRoleId(roleId);
        authUserRole.setUserId(userId);
        authUserRole.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
        authUserRoleService.insert(authUserRole);
        //把权限存进redis
        String roleKey = redisUtil.buildKey(authRolePrefix, authUser.getUserName());
        List<AuthRole> roleList = new LinkedList<>();
        roleList.add(authRole);
        //存用户所属角色
        redisUtil.set(roleKey, new Gson().toJson(roleList));

        AuthRolePermission authRolePermission = new AuthRolePermission();
        authRolePermission.setRoleId(roleId);
        List<AuthRolePermission> authRolePermissionList = authRolePermissionService
                .queryByCondition(authRolePermission);

        List<Long> permissionIdList = authRolePermissionList.stream()
                .map(AuthRolePermission::getPermissionId).collect(Collectors.toList());

        //根据permissionId 去查权限相关信息
        List<AuthPermission> permissionList = authPermissionService.queryByPermissionList(permissionIdList);
        String permissionKey = redisUtil.buildKey(authPermissionPrefix, authUser.getUserName());
        // 存用户所属角色权限
        redisUtil.set(permissionKey, new Gson().toJson(permissionList));
        return count > 0;

    }

    @Override
    public Boolean update(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBOToConverter.INSTANCE.convertToEntity(authUserBO);
        int Count = authUserService.updateByUserName(authUser);
        //有更新与缓存进行同步
        //把权限存进redis
        if (Count > 0) return true;
        return false;
    }

    @Override
    public Boolean delete(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBOToConverter.INSTANCE.convertToEntity(authUserBO);
        authUser.setIsDeleted(1);
        int count = authUserService.updateStatusByUserName(authUser);
        if (count > 0) return true;
        else return false;

    }

//
//    @Override
//    public SaTokenInfo doLogin(String validCode) {
//        String loginKey = redisUtil.buildKey(LOGIN_PREFIX, validCode);
//
//        String openId = redisUtil.get(loginKey);
//        log.info("openId:{}", openId);
//        //判断openId是否存在
//        Preconditions.checkNotNull(openId, "验证码错误");
//        AuthUserBO authUserBO = new AuthUserBO();
//        authUserBO.setUserName(openId);
//        this.register(authUserBO);
//        StpUtil.login(openId);
//        return StpUtil.getTokenInfo();
//    }

    @Override
    public SaTokenInfo doLogin(String validCode) {
        String loginKey = redisUtil.buildKey(LOGIN_PREFIX, validCode);
        String openId = redisUtil.get(loginKey);
        if (StringUtils.isBlank(openId)) {
            return null;
        }
        AuthUserBO authUserBO = new AuthUserBO();
        authUserBO.setUserName(openId);
        this.register(authUserBO);
        StpUtil.login(openId);
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        return tokenInfo;
    }


    @Override
    public AuthUserBO getUserInfo(AuthUserBO authUserBO) {
        AuthUser existAuthUser = new AuthUser();
        existAuthUser.setUserName(authUserBO.getUserName());
        List<AuthUser> existUser = authUserService.queryByCondition(existAuthUser);
        if (CollectionUtils.isNotEmpty(existUser)) {
            log.info("getUserInfo.domain.:{}", JSON.toJSONString(existUser));
            return AuthUserBOToConverter.INSTANCE.convertToBo(existUser.get(0));

        }
        return new AuthUserBO();
    }
}
